import { Style, Fill, Stroke, Circle, Text, Icon } from 'ol/style';

/**
 * 样式缓存，用于缓存和复用样式对象，减少内存占用和提高渲染性能
 */
export class StyleCache {
  private static instance: StyleCache;
  private cache: Map<string, Style> = new Map();
  private maxCacheSize: number = 1000;
  
  /**
   * 获取单例实例
   * @returns StyleCache实例
   */
  static getInstance(): StyleCache {
    if (!StyleCache.instance) {
      StyleCache.instance = new StyleCache();
    }
    return StyleCache.instance;
  }
  
  /**
   * 构造函数
   */
  private constructor() {}
  
  /**
   * 生成样式缓存键
   * @param styleConfig 样式配置对象
   * @returns 缓存键
   */
  private generateCacheKey(styleConfig: any): string {
    // 将样式配置转换为JSON字符串作为缓存键
    // 需要注意对象的顺序以确保相同配置生成相同的键
    return JSON.stringify(this.sortObject(styleConfig));
  }
  
  /**
   * 递归排序对象的键，确保相同内容的对象生成相同的JSON字符串
   * @param obj 要排序的对象
   * @returns 排序后的对象
   */
  private sortObject(obj: any): any {
    if (typeof obj !== 'object' || obj === null) {
      return obj;
    }
    
    if (Array.isArray(obj)) {
      return obj.map(this.sortObject.bind(this));
    }
    
    const sortedObj: any = {};
    Object.keys(obj).sort().forEach(key => {
      sortedObj[key] = this.sortObject(obj[key]);
    });
    
    return sortedObj;
  }
  
  /**
   * 从缓存中获取样式，如果不存在则创建
   * @param styleConfig 样式配置
   * @returns OpenLayers Style对象
   */
  getStyle(styleConfig: any): Style {
    const cacheKey = this.generateCacheKey(styleConfig);
    
    // 检查缓存中是否存在
    if (this.cache.has(cacheKey)) {
      return this.cache.get(cacheKey)!;
    }
    
    // 缓存已满，清理旧缓存（简单的LRU策略）
    if (this.cache.size >= this.maxCacheSize) {
      const firstKey = this.cache.keys().next().value;
      if (firstKey) {
        this.cache.delete(firstKey);
      }
    }
    
    // 创建新样式
    const style = this.createStyle(styleConfig);
    this.cache.set(cacheKey, style);
    
    return style;
  }
  
  /**
   * 根据配置创建OpenLayers Style对象
   * @param styleConfig 样式配置
   * @returns OpenLayers Style对象
   */
  private createStyle(styleConfig: any): Style {
    const styleOptions: any = {};
    
    // 创建填充样式
    if (styleConfig.fill) {
      styleOptions.fill = new Fill(styleConfig.fill);
    }
    
    // 创建描边样式
    if (styleConfig.stroke) {
      styleOptions.stroke = new Stroke(styleConfig.stroke);
    }
    
    // 创建点样式
    if (styleConfig.image) {
      if (styleConfig.image.type === 'circle') {
        styleOptions.image = new Circle(styleConfig.image);
      } else if (styleConfig.image.type === 'icon') {
        styleOptions.image = new Icon(styleConfig.image);
      }
    }
    
    // 创建文本样式
    if (styleConfig.text) {
      styleOptions.text = new Text(styleConfig.text);
    }
    
    return new Style(styleOptions);
  }
  
  /**
   * 清理指定样式的缓存
   * @param styleConfig 样式配置
   */
  removeStyle(styleConfig: any): void {
    const cacheKey = this.generateCacheKey(styleConfig);
    this.cache.delete(cacheKey);
  }
  
  /**
   * 清理所有缓存
   */
  clearCache(): void {
    this.cache.clear();
  }
  
  /**
   * 设置最大缓存大小
   * @param size 最大缓存条目数
   */
  setMaxCacheSize(size: number): void {
    this.maxCacheSize = size;
    
    // 如果当前缓存大小超过新的最大值，清理多余的缓存
    while (this.cache.size > size) {
      const firstKey = this.cache.keys().next().value;
      if (firstKey) {
        this.cache.delete(firstKey);
      }
    }
  }
  
  /**
   * 获取当前缓存大小
   * @returns 缓存条目数
   */
  getCacheSize(): number {
    return this.cache.size;
  }
}